import Vue from 'vue';

import {getJsonVal} from 'src/utils/key_parser';

const marginDataFunc = (lvl: number) => {
    var obj: any = {};
    obj['margin-left'] = (lvl * 20) + 'px';
    return obj;
}

Vue.component('json-node', {
    props: {
        jsonData: {
            type: Object,
        },
        conf: {
            type: Object,
        },

        selectNodeFunc:Function,
    },

    render: function (h: Function) {
        var list: any = [];
        let node:any = this.createNode(h, this.conf, '', 0);
        return h('ul', [node]);
    },

    methods: {
        createNode(h: Function, data: JsonConf, txt: any, level: number): any {
            let nodeList: any = [];
            let self:any = this;
            if (data.type == 'array') {
                let nodeData: VNodeData = {} as any;
                nodeData.domProps = {} as any;
                nodeData.domProps.innerHTML = data.prop + '<span class="array-length">' + data.list.length + '</span>';
                nodeData.methods = {};
                nodeData.methods.click = () => {
                    self.selectNode(data, nodeData);
                }
                nodeData.on = {} as any;
                nodeData.on.click = nodeData.methods.click;
                nodeData.class = {};
                nodeData.class['json-object'] = true;
                nodeData.class['json-item'] = true;
                if(data.selected){
                    nodeData.class['json-node-selected'] = true;
                }else{
                    nodeData.class['json-node-selected'] = false;
                }

                let expandNodeData:VNodeData = {} as any;
                expandNodeData.domProps = {} as any;
                if(data.flag){
                    expandNodeData.domProps.innerHTML = '-';
                }else{
                    expandNodeData.domProps.innerHTML = '+';
                }
                expandNodeData.style = marginDataFunc(level);
                expandNodeData.on = {};
                expandNodeData.class = {};
                expandNodeData.class['json-expand'] = true;
                expandNodeData.on.click = ()=>{
                    data.flag = !data.flag;
                };

                let expandNode = h('span', expandNodeData);
                let objectNode = h('span',  nodeData);

                let node = h('li', [expandNode, objectNode]);
                nodeList.push(node);
                if (data.flag) {
                    data.list.forEach((item: any, ind: number) => {
                        let innerNode: any = this.createNode(h, item, ind, level + 1);
                        nodeList.push(innerNode);
                    })
                }
            } else if (data.type == 'object') {
                let nodeData: VNodeData = {} as any;
                nodeData.props = {};
                // nodeData.style = marginDataFunc(level);
                nodeData.props.data = data;
                nodeData.domProps = {} as any;
                if(data.prop && data.prop != ''){
                    nodeData.domProps.innerHTML = data.prop;
                }else{
                    nodeData.domProps.innerHTML = 'root';
                }
                nodeData.methods = {};
                nodeData.class = {};
                nodeData.class['json-object'] = true;
                nodeData.class['json-item'] = true;
                if(data.selected){
                    nodeData.class['json-node-selected'] = true;
                }else{
                    nodeData.class['json-node-selected'] = false;
                }
                nodeData.methods.click = () => {
                    self.selectNode(data, nodeData);
                }
                nodeData.on = {} as any;
                nodeData.on.click = nodeData.methods.click;

                let expandNodeData:VNodeData = {} as any;
                expandNodeData.domProps = {} as any;
                if(data.flag){
                    expandNodeData.domProps.innerHTML = '-';
                }else{
                    expandNodeData.domProps.innerHTML = '+';
                }
                expandNodeData.style = marginDataFunc(level);
                expandNodeData.on = {};
                expandNodeData.class = {};
                expandNodeData.class['json-expand'] = true;
                expandNodeData.on.click = ()=>{
                    data.flag = !data.flag;
                };
                let expandNode = h('span', expandNodeData);
                let objectNode = h('span',  nodeData);

                let node = h('li', [expandNode, objectNode]);
                nodeList.push(node);
                if (data.flag) {
                    data.list.forEach((item: any, ind: number) => {
                        let innerNode: any = this.createNode(h, item, ind, level + 1);
                        nodeList.push(innerNode);
                    })
                }
            } else {
                let nodeData: VNodeData = {} as any;
                if(data.key == ''){
                    nodeData.domProps = { innerHTML: 'root'};
                }else{
                    nodeData.domProps = { innerHTML: data.prop + ": " + getJsonVal(self.jsonData,  data.key)};
                }

                nodeData.on = {};
                nodeData.on.click = () => {
                    self.selectNode(data, nodeData);
                }
                nodeData.style = marginDataFunc(level);
                nodeData.class = {};
                nodeData.class['json-item'] = true;
                if(data.selected){
                    nodeData.class['json-node-selected'] = true;
                    if(data.clickFlag){
                        nodeData.class['json-selected-anim1'] = true;
                        nodeData.class['json-selected-anim2'] = false;
                    }else{
                        nodeData.class['json-selected-anim2'] = true;
                        nodeData.class['json-selected-anim1'] = false;
                    }
                }else{
                    nodeData.class['json-node-selected'] = false;
                }

                if (data.type == 'string') {
                    nodeData.class['json-string'] = true;
                } else if (data.type == 'number') {
                    nodeData.class['json-number'] = true;
                } else if (data.type == 'boolean') {
                    nodeData.class['json-boolean'] = true;
                }
                let node: any = h('li', nodeData);
                nodeList.push(node);
            }

            return h('li', nodeList);
        },

        resetSelected(conf:JsonConf){
            conf.selected = false;
            if(wlIsNotNullArray(conf.list)){
                conf.list.forEach((inner:JsonConf)=>{
                    this.resetSelected(inner);
                });
            }
        },

        selectNode(data:JsonConf, vdata:VNodeData){
            var self:any = this;
            
            this.resetSelected(self.conf);
            data.selected = true;
            let param:any = {}
            param.json= self.jsonData;
            param.nodeConf = data;
            param.conf = self.conf;
            param.val = getJsonVal(self.jsonData, data.key);
            if(wlIsFunc(self.selectNodeFunc)){
                self.selectNodeFunc(param);
            }
            data.clickFlag = !data.clickFlag;
        }
    }
} as any);